using System;
using System.Threading;

namespace AsyncLibrary.StatusListener
{
  /// <summary>Makes synchronious decorator</summary>
  public class SyncedStatusListener : IStatusListener
  {
    private readonly IStatusListener _target;
    private readonly SynchronizationContext _syncContext;

    /// <summary>Ctor</summary>
    public SyncedStatusListener(IStatusListener target, SynchronizationContext syncContext)
    {
      _target = target;
      _syncContext = syncContext;
    }

    /// <summary>Set progress of current operation</summary>
    public void SetProgress(int value)
    {
      _syncContext.Post(status => _target.SetProgress((int) status), value);
    }

    /// <summary>Set max progress value</summary>
    public void SetProgresMax(int value)
    {
      _syncContext.Post(status => _target.SetProgresMax((int) status), value);
    }

    /// <summary>Set progress mode</summary>
    public void SetMode(StatusProgressMode value)
    {
      _syncContext.Post(status => _target.SetMode((StatusProgressMode) status), value);
    }

    /// <summary>Set main status message</summary>
    /// <remarks>Usually current action is sent here</remarks>
    public void SetStatus(string message)
    {
      _syncContext.Post(status => _target.SetStatus((string) status), message);
    }

    /// <summary>Set additional information</summary>
    /// <remarks>Usually current action details, 
    ///   like percents or bytes count</remarks>
    public void SetInfo(string text)
    {
      _syncContext.Post(status => _target.SetInfo((string) status), text);
    }

    /// <summary>Reports about fatal error. 
    ///   Operation is going to close immediately.</summary>
    /// <param name="ex">fata error reason</param>
    public void FatalError(Exception ex)
    {
      _syncContext.Post(status => _target.FatalError((Exception)status), ex);
    }
  }
}